package com.chatsystem.repository;

import com.chatsystem.entity.Message;
import com.chatsystem.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 消息数据访问层
 * 
 * @author ChatSystem
 * @version 1.0.0
 */
@Repository
public interface MessageRepository extends JpaRepository<Message, Long> {

    /**
     * 查找两个用户之间的消息记录
     * 
     * @param user1 用户1
     * @param user2 用户2
     * @param pageable 分页参数
     * @return 消息分页
     */
    @Query(value = "SELECT m FROM Message m JOIN FETCH m.sender JOIN FETCH m.receiver WHERE " +
           "(m.sender = :user1 AND m.receiver = :user2) OR " +
           "(m.sender = :user2 AND m.receiver = :user1) " +
           "ORDER BY m.createdAt DESC",
           countQuery = "SELECT COUNT(m) FROM Message m WHERE " +
           "(m.sender = :user1 AND m.receiver = :user2) OR " +
           "(m.sender = :user2 AND m.receiver = :user1)")
    Page<Message> findMessagesBetweenUsers(@Param("user1") User user1, 
                                          @Param("user2") User user2, 
                                          Pageable pageable);

    /**
     * 查找用户的所有未读消息
     * 
     * @param receiver 接收者
     * @return 未读消息列表
     */
    List<Message> findByReceiverAndIsReadFalseOrderByCreatedAtDesc(User receiver);

    /**
     * 统计用户未读消息数量
     * 
     * @param receiver 接收者
     * @return 未读消息数量
     */
    long countByReceiverAndIsReadFalse(User receiver);

    /**
     * 查找指定时间范围内的消息
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 消息列表
     */
    List<Message> findByCreatedAtBetweenOrderByCreatedAtDesc(LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 查找可以撤回的消息（1分钟内）
     * 
     * @param sender 发送者
     * @param timeLimit 时间限制
     * @return 可撤回的消息列表
     */
    @Query("SELECT m FROM Message m WHERE m.sender = :sender AND m.createdAt >= :timeLimit AND m.isRecalled = false")
    List<Message> findRecallableMessages(@Param("sender") User sender, @Param("timeLimit") LocalDateTime timeLimit);

    /**
     * 根据消息类型查找消息
     * 
     * @param messageType 消息类型
     * @param pageable 分页参数
     * @return 消息分页
     */
    Page<Message> findByMessageType(Message.MessageType messageType, Pageable pageable);
} 